Crate system_deps[−][src]
Expand description
system-deps
lets you write system dependencies in Cargo.toml
metadata,
rather than programmatically in build.rs
. This makes those dependencies
declarative, so other tools can read them as well.
Usage
In your Cargo.toml
:
[build-dependencies]
system-deps = "2.0"
Then, to declare a dependency on testlib >= 1.2
add the following section:
[package.metadata.system-deps]
testlib = "1.2"
Finally, in your build.rs
, add:
fn main() {
system_deps::Config::new().probe().unwrap();
}
Feature-specific dependency
You can easily declare an optional system dependency by associating it with a feature:
[package.metadata.system-deps]
testdata = { version = "4.5", feature = "use-testdata" }
system-deps
will check for testdata
only if the use-testdata
feature has been enabled.
Optional dependency
Another option is to use the optional
setting, which can also be used using features versions:
[package.metadata.system-deps]
test-data = { version = "4.5", optional = true }
testmore = { version = "2", v3 = { version = "3.0", optional = true }}
system-deps
will automatically export for each dependency a feature system_deps_have_$DEP
where $DEP
is the toml
key defining the dependency in snake_case.
This can be used to check if an optional dependency has been found or not:
#[cfg(system_deps_have_testdata)]
println!("found test-data");
Overriding library name
toml
keys cannot contain dot characters so if your library name does, you can define it using the name
field:
[package.metadata.system-deps]
glib = { name = "glib-2.0", version = "2.64" }
Feature versions
-sys
crates willing to support various versions of their underlying system libraries
can use features to control the version of the dependency required.
system-deps
will pick the highest version among enabled features.
Such version features must use the pattern v1_0
, v1_2
, etc.
[features]
v1_2 = []
v1_4 = ["v1_2"]
v1_6 = ["v1_4"]
[package.metadata.system-deps.gstreamer_1_0]
name = "gstreamer-1.0"
version = "1.0"
v1_2 = { version = "1.2" }
v1_4 = { version = "1.4" }
v1_6 = { version = "1.6" }
The same mechanism can be used to require a different library name depending on the version:
[package.metadata.system-deps.gst_gl]
name = "gstreamer-gl-1.0"
version = "1.14"
v1_18 = { version = "1.18", name = "gstreamer-gl-egl-1.0" }
Target specific dependencies
You can define target specific dependencies:
[package.metadata.system-deps.'cfg(target_os = "linux")']
testdata = "1"
[package.metadata.system-deps.'cfg(not(target_os = "macos"))']
testlib = "1"
[package.metadata.system-deps.'cfg(unix)']
testanotherlib = { version = "1", optional = true }
See the Rust documentation for the exact syntax. Currently, those keys are supported:
target_arch
target_endian
target_env
target_family
target_os
target_pointer_width
target_vendor
unix
andwindows
Overriding build flags
By default system-deps
automatically defines the required build flags for each dependency using the information fetched from pkg-config
.
These flags can be overridden using environment variables if needed:
SYSTEM_DEPS_$NAME_SEARCH_NATIVE
to override thecargo:rustc-link-search=native
flag;SYSTEM_DEPS_$NAME_SEARCH_FRAMEWORK
to override thecargo:rustc-link-search=framework
flag;SYSTEM_DEPS_$NAME_LIB
to override thecargo:rustc-link-lib
flag;SYSTEM_DEPS_$NAME_LIB_FRAMEWORK
to override thecargo:rustc-link-lib=framework
flag;SYSTEM_DEPS_$NAME_INCLUDE
to override thecargo:include
flag.
With $NAME
being the upper case name of the key defining the dependency in Cargo.toml
.
For example SYSTEM_DEPS_TESTLIB_SEARCH_NATIVE=/opt/lib
could be used to override a dependency named testlib
.
One can also define the environment variable SYSTEM_DEPS_$NAME_NO_PKG_CONFIG
to fully disable pkg-config
lookup
for the given dependency. In this case at least SYSTEM_DEPS_$NAME_LIB or SYSTEM_DEPS_$NAME_LIB_FRAMEWORK should be defined as well.
Internally build system libraries
-sys
crates can provide support for building and statically link their underlying system library as part of their build process.
Here is how to do this in your build.rs
:
fn main() {
system_deps::Config::new()
.add_build_internal("testlib", |lib, version| {
// Actually build the library here
system_deps::Library::from_internal_pkg_config("build/path-to-pc-file", lib, version)
})
.probe()
.unwrap();
}
This feature can be controlled using the SYSTEM_DEPS_$NAME_BUILD_INTERNAL
environment variable
which can have the following values:
auto
: build the dependency only if the required version has not been found bypkg-config
;always
: always build the dependency, ignoring any version which may be installed on the system;never
: (default) never build the dependency,system-deps
will fail if the required version is not found on the system.
You can also use the SYSTEM_DEPS_BUILD_INTERNAL
environment variable with the same values
defining the behavior for all the dependencies which don’t have SYSTEM_DEPS_$NAME_BUILD_INTERNAL
defined.
Static linking
By default all libraries are dynamically linked, except when build internally as described above.
Libraries can be statically linked by defining the environment variable SYSTEM_DEPS_$NAME_LINK=static
.
You can also use SYSTEM_DEPS_LINK=static
to statically link all the libraries.
Structs
Structure used to configure metadata
before starting to probe for dependencies
All the system dependencies retrieved by Config::probe.
Internal library name and if a static library is available on the system
A system dependency
Enums
Error used in return value of Config::add_build_internal
closures
system-deps errors
From where the library settings have been retrieved